import React, { ReactNode, useEffect, useRef, useState } from 'react';
import useSyncState from '../hooks/useSyncState';

import { enableTTS, startSpeaking, stopSpeaking, stopTTS, getVariableWithSessionId } from '@/api';
import { useSelector } from 'react-redux';

import AgentService from '@/modules/Agent';
import Message from '@/utils/message';
import { useTranslation } from 'react-i18next';
import { startTtsSpeakingErrorResponse, cancelTtsSpeakingErrorResponse } from '@/modules/errorResponse';

const defaultInitialState: string = 'idle';

const TTSBoardCast = React.createContext<
	| {
			TTSBoardCastStats: () => string;
			setTTSBoardCastStats: (data: string) => void;
			TTSBoardCastText: () => string;
			setTTSBoardCastText: (TTSBoardCastText: string) => void;
			EditModal: () => boolean;
			setEditModal: (EditModal: boolean) => void;
			BoardCastModal: () => boolean;
			setBoardCastModal: (BoardCastModal: boolean) => void;
			Speaking: () => boolean;
			setSpeaking: (Speaking: boolean) => void;
			startTTSPassAgeway: () => void;
			stopSpeak: () => void;
			getVariableValue: () => void;
			variableList: () => any[];
			cancelTTSWithRecordMessage: (message: string) => void;
			selectedVariableList: () => any[];
			setSelectedVariableList: (data: any) => void;
	  }
	| undefined
>(undefined);
TTSBoardCast.displayName = 'TTSBoardCastContext';

const TTSBoardCastProvider = ({ children }: { children: ReactNode }) => {
	const { t } = useTranslation();
	const { session } = useSelector((state: any) => state);

	const [TTSBoardCastStats, setTTSBoardCastStats] = useSyncState<string>(defaultInitialState); //idle禁用 default默认 open展开 stow收起

	const [TTSBoardCastText, setTTSBoardCastText] = useSyncState<string>('');

	const [EditModal, setEditModal] = useSyncState<boolean>(false);

	const [BoardCastModal, setBoardCastModal] = useSyncState<boolean>(false);

	const [Speaking, setSpeaking] = useSyncState<boolean>(false);

	const [TTSID, setTTSID] = useSyncState<string>('');

	const [variableList, setVariableList] = useSyncState<any[]>([]);

	const [selectedVariableList, setSelectedVariableList] = useSyncState<any[]>([]);

	const eventRef = useRef<boolean>(false);

	useEffect(() => {
		if (!AgentService.sessionId) {
			eventRef.current = false;
			setTTSID('');
			setSpeaking(false);
		} else {
			AgentService.fetchTTSTalksWithPageSize({ scenId: AgentService.bizScenarioId, page: 1, pageSize: 999 });
		}
	}, [AgentService.sessionId]);

	useEffect(() => {
		if (!eventRef.current && TTSID()) {
			eventRef.current = true;
			onTTSStreamSpeaking();
			onTTSStreamSpeakDone();
		}
	}, [TTSID()]);

	const getVariableValue = async () => {
		try {
			const { data } = await getVariableWithSessionId(AgentService.sessionId, AgentService.bizScenarioId);
			setVariableList(Object.values(data.data));
		} catch (error) {
			console.log(error, 'getVariableValue');
			Message.error(t('get-variable-failed'));
		}
	};

	const startTTSPassAgeway = () => {
		const data = {
			type: 'aliyun',
			owner: AgentService.participantId,
			attributes: {
				type: 'tts' + AgentService.user?.clientId,
				userInfo: {
					clientId: AgentService.user?.clientId,
					userName: AgentService.user?.userName
				}
			}
		};
		enableTTS(AgentService.roomId, data).then(
			async resp => {
				if (resp.status === 200 && resp.data && resp.data.id) {
					setTTSID(resp.data.id);
					await startSpeak(resp.data.id);
				}
			},
			error => {
				console.log(error, 'enable TTS error');
				setBoardCastModal(false);
				Message.error(t('start-tts-failed'));
			}
		);
	};

	const stopTTSPassAgeway = async () => {
		try {
			const { data } = await stopTTS(AgentService.roomId, TTSID());
			console.log(data, 'stopTTSPassAgeway');
			setSpeaking(false);
			setTTSBoardCastStats('default');
		} catch (error) {
			console.log(error, 'stop tts error');
			Message.error(t('stop-tts-failed'));
		}
	};

	const stopSpeak = () => {
		stopSpeaking(AgentService.roomId, TTSID()).then(
			async resp => {
				if (resp.status === 200) {
					await stopTTSPassAgeway();
				}
			},
			error => {
				console.log(error, 'stop speak error');
				Message.error(t('stop-tts-speak-failed'));
			}
		);
	};

	const startSpeak = async (ttsId: string) => {
		const resulut = {
			speech: TTSBoardCastText(),
			params: null
		};
		console.log('startSpeak:', TTSBoardCastText());

		try {
			const { data } = await startSpeaking(AgentService.roomId, ttsId, resulut);
			setTTSBoardCastStats('stow');
			startTTSWithRecordMessage(TTSBoardCastText());
		} catch (error) {
			console.log(error, 'start speaking error');
			setBoardCastModal(false);
			Message.error(t('start-tts-speak-failed'));
		}
	};

	const onTTSStreamSpeaking = () => {
		ivcs.agent.onTTSStreamSpeaking((data: { userInfo: { clientId: string | undefined }; content: string }) => {
			console.log(data, 'onTTSStreamSpeaking');
			if (data.userInfo.clientId === AgentService.user?.clientId) {
				setSpeaking(true);
				sendTTSBroadMessage(data.content);
			}
		});
	};

	const onTTSStreamSpeakDone = () => {
		ivcs.agent.onTTSStreamSpeakDone((data: { userInfo: { clientId: string | undefined }; content: string; streamLabel: string }) => {
			console.log(data, 'onTTSStreamSpeakDone');
			// content ok 正常读完 stopped异常终止
			if (data.userInfo.clientId === AgentService.user?.clientId && data.content === 'ok' && data.streamLabel === 'tts' + AgentService.user?.clientId) {
				stopSpeak();
				setSpeaking(false);
				setTTSBoardCastStats('default');
				setBoardCastModal(false);
				Message.normal(t('tts-broadcast-ended'));
			}
		});
	};

	const sendTTSBroadMessage = (message: string) => {
		ivcs.agent.sendTTSBroadMessage(
			message,
			'all',
			(resp: any) => {
				console.log(resp, 'send tts text message success');
			},
			(error: any) => {
				console.log(error, 'send tts text message error');
			}
		);
	};

	const startTTSWithRecordMessage = (message: string) => {
		ivcs.agent.startTtsSpeaking(
			message,
			'all',
			(resp: any) => {
				console.log(resp, 'start tts speaking success');
			},
			(error: any) => {
				console.log(error, 'start tts speaking error');
				startTtsSpeakingErrorResponse(error.code || '');
			}
		);
	};

	const cancelTTSWithRecordMessage = (message: string) => {
		ivcs.agent.cancelTtsSpeaking(
			message,
			'all',
			(resp: any) => {
				console.log(resp, 'cancel tts speaking success');
			},
			(error: any) => {
				console.log(error, 'cancel tts speaking error');
				cancelTtsSpeakingErrorResponse(error.code || '');
			}
		);
	};

	return (
		<TTSBoardCast.Provider
			children={children}
			value={{
				TTSBoardCastStats,
				setTTSBoardCastStats,
				TTSBoardCastText,
				setTTSBoardCastText,
				EditModal,
				setEditModal,
				BoardCastModal,
				setBoardCastModal,
				Speaking,
				setSpeaking,
				startTTSPassAgeway,
				stopSpeak,
				getVariableValue,
				variableList,
				cancelTTSWithRecordMessage,
				selectedVariableList,
				setSelectedVariableList
			}}
		></TTSBoardCast.Provider>
	);
};

const useTTSBoardCast = () => {
	const context = React.useContext(TTSBoardCast);
	if (!context) {
		throw new Error('useScreenSync 必须在 AppProvider 中使用');
	}
	return context;
};

export { useTTSBoardCast, TTSBoardCastProvider };
